package com.ebocy.hammer.world;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.ebocy.hammer.core.handler.HandlerManager;
import com.ebocy.hammer.core.init.MapLoader;
import com.ebocy.hammer.core.init.StaticDataLoader;
import com.ebocy.hammer.core.socket.MessageFilter;
import com.ebocy.hammer.core.socket.codecFilter.AsRequestDecoder;
import com.ebocy.hammer.core.socket.codecFilter.AsResponseEncoder;
import com.ebocy.hammer.core.socket.server.AbstractServer;
import com.ebocy.hammer.core.socket.server.ServerIoHandler;
import com.ebocy.hammer.core.util.Config;
import com.ebocy.hammer.world.handler.WorldHandler;
import com.ebocy.hammer.world.resourceManage.XmlLoader;

/**
 * @author Qingrong Hou
 *
 *         May 15, 2012
 */
public class WorldServer extends AbstractServer {
	private static AbstractServer server = null;

	private WorldServer() {
	}

	public static AbstractServer getInstance() {
		if (server == null) {
			server = new WorldServer();
		}
		return server;
	}

	@Override
	protected void startSocketService() {
		NioSocketAcceptor acceptor = new NioSocketAcceptor();
		try {
//			acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
			acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter());
			acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new AsResponseEncoder(),  new AsRequestDecoder()));
			acceptor.getFilterChain().addLast("message", new MessageFilter());
			// inject an ExecutorFilter for the message received operations
//			acceptor.getFilterChain().addLast("executor", new ExecutorFilter(Executors.newCachedThreadPool(), IoEventType.MESSAGE_RECEIVED));
			acceptor.setHandler(new ServerIoHandler(acceptor));
			SocketSessionConfig sessionConfig = acceptor.getSessionConfig();
			sessionConfig.setTcpNoDelay(true);
			acceptor.bind(new InetSocketAddress(Config.serverPort));
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("socket service start failed！port=" + Config.serverPort, e);
			System.exit(0);
		}
		logger.info("socket  started on port " + Config.serverPort);

		// // 与其他game server建立连接
		// for (ServerAddress serverAddress : Config.gameServer) {
		// SocketConnect connector = new SocketConnect();
		// connector.setHandler(new SenderHandler());
		// connector.connect(serverAddress);
		// }
	}

	/**
	 * 注册业务处理器
	 */
	@Override
	protected void registerHandlers() {
		HandlerManager.registerHandler(WorldHandler.getInstance());
		logger.info("业务处理器注册完成！");
	}

	@Override
	protected void checkServer() {
		logger.info("服务器状态检查完成！");
	}

	@Override
	protected void initialization() {
		super.initialization();
		super.init(WorldServer.class);
		XmlLoader.xmlInit();
		MapLoader.initMapData();
		StaticDataLoader.dataLoader();
	}

	public static void main(String[] args) {
		AbstractServer server = WorldServer.getInstance();
		server.startServer();
		// HeartBeatRunner beatRunner = new HeartBeatRunner();
		// try {
		// beatRunner.run();
		// } catch (Exception e) {
		// logger.error("定时任务启动失败！", e);
		// System.exit(0);
		// }
	}

}
